From: kaf24@firebug.cl.cam.ac.uk Date: Wed, 21 Jun 2006 16:09:14 +0000 (+0100) Subject: [XEN] localtime support for paravirtualized guests X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~15921^2~6 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22Dat/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22Dat?a=commitdiff_plain;h=42fae7ae020c9fc18010f5e92516bd95fd6992b1;p=xen.git [XEN] localtime support for paravirtualized guests It is quite minimal in its approach, satisfying the purposes of the paravirtualized NetWare operating system as well as any others that expect the time base to be provided in localtime. Signed-off-by: Bruce Rogers --- diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index 4f1d8561da..51117117f4 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -286,6 +286,17 @@ int xc_domain_setmaxmem(int xc_handle, return do_dom0_op(xc_handle, &op); } +int xc_domain_set_time_offset(int xc_handle, + uint32_t domid, + int32_t time_offset_seconds) +{ + DECLARE_DOM0_OP; + op.cmd = DOM0_SETTIMEOFFSET; + op.u.settimeoffset.domain = (domid_t)domid; + op.u.settimeoffset.time_offset_seconds = time_offset_seconds; + return do_dom0_op(xc_handle, &op); +} + int xc_domain_memory_increase_reservation(int xc_handle, uint32_t domid, unsigned long nr_extents, diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index f6093752b6..c18f1807ab 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -410,6 +410,10 @@ int xc_domain_setmaxmem(int xc_handle, uint32_t domid, unsigned int max_memkb); +int xc_domain_set_time_offset(int xc_handle, + uint32_t domid, + int32_t time_offset_seconds); + int xc_domain_memory_increase_reservation(int xc_handle, uint32_t domid, unsigned long nr_extents, diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index d85f0f7107..db42ab058a 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -869,6 +869,30 @@ static PyObject *pyxc_domain_iomem_permission(PyObject *self, return zero; } +static PyObject *pyxc_domain_set_time_offset(XcObject *self, PyObject *args) +{ + uint32_t dom; + int32_t time_offset_seconds; + time_t calendar_time; + struct tm local_time; + struct tm utc_time; + + if (!PyArg_ParseTuple(args, "i", &dom)) + return NULL; + + calendar_time = time(NULL); + localtime_r(&calendar_time, &local_time); + gmtime_r(&calendar_time, &utc_time); + /* set up to get calendar time based on utc_time, with local dst setting */ + utc_time.tm_isdst = local_time.tm_isdst; + time_offset_seconds = (int32_t)difftime(calendar_time, mktime(&utc_time)); + + if (xc_domain_set_time_offset(self->xc_handle, dom, time_offset_seconds) != 0) + return NULL; + + Py_INCREF(zero); + return zero; +} static PyObject *dom_op(XcObject *self, PyObject *args, int (*fn)(int, uint32_t)) @@ -1208,6 +1232,13 @@ static PyMethodDef pyxc_methods[] = { "Returns: [int]: The size in KiB of memory spanning the given number " "of pages.\n" }, + { "domain_set_time_offset", + (PyCFunction)pyxc_domain_set_time_offset, + METH_VARARGS, "\n" + "Set a domain's time offset to Dom0's localtime\n" + " dom [int]: Domain whose time offset is being set.\n" + "Returns: [int] 0 on success; -1 on error.\n" }, + { NULL, NULL, 0, NULL } }; diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 0dd3a54eef..665eb927d3 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -135,6 +135,7 @@ ROUNDTRIPPING_CONFIG_ENTRIES = [ ('bootloader', str), ('bootloader_args', str), ('features', str), + ('localtime', int), ] ROUNDTRIPPING_CONFIG_ENTRIES += VM_CONFIG_PARAMS @@ -1260,6 +1261,10 @@ class XendDomainInfo: self.info['image'], self.info['device']) + localtime = self.info['localtime'] + if localtime is not None and localtime == 1: + xc.domain_set_time_offset(self.domid) + xc.domain_setcpuweight(self.domid, self.info['cpu_weight']) # repin domain vcpus if a restricted cpus list is provided diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index f4e05ae667..3eadebb37d 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -672,6 +672,8 @@ def make_config(vals): config.append(['backend', ['netif']]) if vals.tpmif: config.append(['backend', ['tpmif']]) + if vals.localtime: + config.append(['localtime', vals.localtime]) config_image = configure_image(vals) if vals.bootloader: diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index 54a3ce41d4..9d344b8349 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -699,7 +699,7 @@ void update_domain_wallclock_time(struct domain *d) { spin_lock(&wc_lock); version_update_begin(&d->shared_info->wc_version); - d->shared_info->wc_sec = wc_sec; + d->shared_info->wc_sec = wc_sec + d->time_offset_seconds; d->shared_info->wc_nsec = wc_nsec; version_update_end(&d->shared_info->wc_version); spin_unlock(&wc_lock); diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index a6e437abd1..91cbc60be8 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -693,6 +693,21 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) break; #endif + case DOM0_SETTIMEOFFSET: + { + struct domain *d; + + ret = -ESRCH; + d = find_domain_by_id(op->u.settimeoffset.domain); + if ( d != NULL ) + { + d->time_offset_seconds = op->u.settimeoffset.time_offset_seconds; + put_domain(d); + ret = 0; + } + } + break; + default: ret = arch_do_dom0_op(op, u_dom0_op); break; diff --git a/xen/include/public/dom0_ops.h b/xen/include/public/dom0_ops.h index 07affaa699..d1113b655b 100644 --- a/xen/include/public/dom0_ops.h +++ b/xen/include/public/dom0_ops.h @@ -527,6 +527,14 @@ typedef struct dom0_domain_setup { } dom0_domain_setup_t; DEFINE_XEN_GUEST_HANDLE(dom0_domain_setup_t); +#define DOM0_SETTIMEOFFSET 50 +struct dom0_settimeoffset { + domid_t domain; + int32_t time_offset_seconds; /* applied to domain wallclock time */ +}; +typedef struct dom0_settimeoffset dom0_settimeoffset_t; +DEFINE_XEN_GUEST_HANDLE(dom0_settimeoffset_t); + struct dom0_op { uint32_t cmd; uint32_t interface_version; /* DOM0_INTERFACE_VERSION */ @@ -569,6 +577,7 @@ struct dom0_op { struct dom0_iomem_permission iomem_permission; struct dom0_hypercall_init hypercall_init; struct dom0_domain_setup domain_setup; + struct dom0_settimeoffset settimeoffset; uint8_t pad[128]; } u; }; diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 70869a51af..e78ff4f619 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -159,6 +159,7 @@ struct domain /* OProfile support. */ struct xenoprof *xenoprof; + int32_t time_offset_seconds; }; struct domain_setup_info